1. /* sdfatanh.cpp by K.Tsuru */
  2. // function ID 3311 DRADIX
  3. /*************************************************************************
  4. SDouble class
  5. inverse hyperbolic artanh x(area tanh) defined by
  6. artanh x = (1/2)*log( (1+x)/(1-x) ) (|x|<1.0)
  7. When |x| is very near to 1.0 a large error causes
  8. in this case series expansion
  9. atanh(x) = (1/2)*log( (1+x)/(1-x) ) = x + x^3/3+x^5/5 + ...
  10. must be used. See AtanhSeries(x)
  11. *************************************************************************/
  12. #ifndef SN_H
  13. #include "sn.h"
  14. #endif
  15. static const char* const func = "Atanh";
  16. #define usesAtanhSeriesInAtanh 0
  17. // for test. =1(use) 76.5sec(very slow), =0(no use) 13.4sec when 10,000 eff figs
  18. SDouble Atanh(const SDouble& x){
  19. if(x.Sign(3311) == 0) return 0.0;
  20. #if usesAtanhSeriesInAtanh
  21. if(x.NetRdxExp() < 0) return AtanhSeries(x); // |x| <1/DRADIX
  22. uint fig = x.Last() - x.First() + 1u;
  23. if(fig <= 4){ // short and small
  24. double xd = fabs(doubleD(x, 0));
  25. if(xd < 0.15) return AtanhSeries(x); // |x| < 0.15
  26. }
  27. #endif
  28. SDouble X(Dabs(x)), r; // X > 0
  29. r = ONE - X;
  30. if(r.Sign(3311) <= 0 || r.IsMLT(ONE)) x.SetError(x.DOMAIN_ERR, func, 3311); // x >= 1.0
  31. // here r > 0
  32. r = (ONE + X)/r; // > 0
  33. r = Log(r);
  34. r = DsDiv(r, 2);
  35. return x.Sign(3311) > 0 ? r : -r;
  36. }

sdfatanh.cpp : last modifiled at 2016/08/29 16:49:53(1,302 bytes)
created at 2017/10/07 10:22:50
The creation time of this html file is 2017/10/07 11:29:39 (Sat Oct 07 11:29:39 2017).